package mms.farina.thecell.activities;



import mms.farina.thecell.Notifier;
import mms.farina.thecell.R;
import mms.farina.thecell.Sender;
import mms.farina.thecell.Sender2;
import mms.farina.thecell.messages.CustomMessage;
import mms.farina.thecell.services.GeoInfoService;
import mms.farina.thecell.services.ReceiveService;
import mms.farina.thecell.support.ErrorCodes;
import mms.farina.thecell.support.IO;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;

import android.location.LocationManager;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
import android.provider.Settings;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import android.widget.ToggleButton;

public class MainActivity extends Activity {

	Dialog regDialog; /**Dialogo di registrazione*/
	Dialog sendDialog; /**Dialogo di invio degli alert messages*/
	public static Handler regProgressHandler; /**Handler usato per la gestione di errori in fase di accesso alla rete*/
	public static Handler recvHandler; /**Handler che si occupa della gestione dei messaggi in console*/
	public static Handler startServiceHandler; /**Handler per l'inizializzazione dei servizi*/

	public static Notifier notifier;
	public static boolean active=false;
	public static boolean end=false;
	public static boolean geoserviceActive=false;
	private static boolean sysActive=false;
	private ConditionVariable mCond;
	public static Thread progressThread;/**Thread che si occupa della procedura di autenticaziane e accesso alla rete*/
	private String tmppwd="";
	private String tmpip="";
	private int tmpport=0;
	ProgressDialog myProgressDialog = null;
	



	/**Thread che si occupa della procedura di autenticaziane e accesso alla rete*/
	private Runnable mTask = new Runnable() {
		public void run() {
			Looper.prepare();

			boolean authRes=serverAuthentication(tmppwd, tmpip, tmpport);
			if(!authRes){sendError(ErrorCodes.AUTHENTICATION_FAILED_MSG, ErrorCodes.AUTHENTICATION_FAILED); myProgressDialog.dismiss(); return;}
			else {sendToConsole(ErrorCodes.AUTHENTICATION_SUCCESS_MSG, ErrorCodes.AUTHENTICATION_SUCCESS); startServiceHandler.sendEmptyMessage(0);}

			myProgressDialog.dismiss();

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Button sendButton = (Button) findViewById(R.id.sendmainButton);
		Button showButton = (Button) findViewById(R.id.showmainButton);
		Button alertButton = (Button) findViewById(R.id.alertButton);
		ToggleButton gpsButton = (ToggleButton) findViewById(R.id.geolocButton);
		Button joinButton = (Button) findViewById(R.id.regMainButton);
		if(!sysActive){
			sendButton.setEnabled(false);
			showButton.setEnabled(false);
			alertButton.setEnabled(false);
			gpsButton.setEnabled(false);
		}
		else joinButton.setText(R.string.endButton);
		if(geoserviceActive)gpsButton.setChecked(true);
		active=true;
		notifier=new Notifier(this);
		notifier.mainNotificationNoIntent();
		handlerInitializer();
		StrictMode.ThreadPolicy tp = ThreadPolicy.LAX;
		StrictMode.setThreadPolicy(tp);
		
		end=false;
		mCond = new ConditionVariable();
		mCond.close();


	}

	/**Inizializza gli handler*/
	void handlerInitializer(){

		/**Handler usato per la gestione di errori in fase di accesso alla rete*/
		regProgressHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);

				EditText name = (EditText) findViewById(R.id.mainConsole);
				name.append(((String)msg.obj)+"("+msg.what+")"+"\n");

				Button sendButton = (Button) findViewById(R.id.sendmainButton);
				Button showButton = (Button) findViewById(R.id.showmainButton);
				Button alertButton = (Button) findViewById(R.id.alertButton);
				ToggleButton gpsButton = (ToggleButton) findViewById(R.id.geolocButton);
				Button joinButton = (Button) findViewById(R.id.regMainButton);
				sendButton.setEnabled(false);
				showButton.setEnabled(false);
				alertButton.setEnabled(false);
				gpsButton.setChecked(false);
				gpsButton.setEnabled(false);
				joinButton.setText(R.string.joinNet);
				geoserviceActive=false;

				stopService(new Intent(MainActivity.this, ReceiveService.class));
				stopService(new Intent(MainActivity.this, GeoInfoService.class));

				Toast toast = Toast.makeText(MainActivity.this, (String)msg.obj, Toast.LENGTH_LONG);
				toast.show();
				sysActive=false;

				return;
			}
		};
		
		/**Handler che si occupa della gestione dei messaggi in console*/
		recvHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);

				EditText name = (EditText) findViewById(R.id.mainConsole);
				name.append(((String)msg.obj)+"\n");

				return;
			}
		};
		
		/**Handler per l'inizializzazione dei servizi*/
		startServiceHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				MainActivity.this.startService(new Intent(MainActivity.this, ReceiveService.class));
				MainActivity.this.startService(new Intent(MainActivity.this, GeoInfoService.class));
				Button sendButton = (Button) findViewById(R.id.sendmainButton);
				Button showButton = (Button) findViewById(R.id.showmainButton);
				Button alertButton = (Button) findViewById(R.id.alertButton);
				Button joinButton = (Button) findViewById(R.id.regMainButton);
				ToggleButton gpsButton = (ToggleButton) findViewById(R.id.geolocButton);
				sendButton.setEnabled(true);
				showButton.setEnabled(true);
				alertButton.setEnabled(true);
				gpsButton.setEnabled(true);
				joinButton.setText(R.string.endButton);
				sysActive=true;

				return;
			}
		};

	}
	
	/**Invia un messaggio alla console*/
	private void sendToConsole(String message, int code){
		Message m=new Message();
		m.obj=message;
		m.what=code;
		MainActivity.recvHandler.sendMessage(m);
	}

	/**Invia un messaggio di ERRORE alla console*/
	private void sendError(String message, int code){
		Message m=new Message();
		m.obj=message;
		m.what=code;
		MainActivity.regProgressHandler.sendMessage(m);
	}
	
	/**Effettua l'autenticazione con il server*/
	private boolean serverAuthentication(String pwd, String ip, int port){
		
		if(pwd.isEmpty()){sendToConsole("Empty Password!", 0); return false;}
		Sender sender=new Sender();
		CustomMessage snounce=sender.sendRecvGenericMessage(new CustomMessage(CustomMessage.MESSAGE_TYPE_ATUHREQ, ""), ip, port);
		if(snounce==null)return false;
		CustomMessage response1=sender.sendRecvGenericMessage(new CustomMessage(CustomMessage.MESSAGE_TYPE_ATUHREQ2, pwd), ip, port);
		if(response1==null)return false;
		if(response1.getSender_nick().equals("NACK")){return false;}
		CustomMessage response2=sender.sendRecvGenericMessage(new CustomMessage(CustomMessage.MESSAGE_TYPE_ATUHREQ3, ""), ip, port);
		if(response2==null)return false;
		if(!pwd.equals(response2.getSender_nick())){return false;}


		return true;
	}




	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	public void joinButtonListener(View v){


		if(sysActive) sendError("Connection Stopped", 12);	
		else{

			AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
			LayoutInflater inflater = MainActivity.this.getLayoutInflater();		
			builder.setView(inflater.inflate(R.layout.dialog_registration, null));



			builder
			.setPositiveButton(R.string.joinNet, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {


					EditText name = (EditText) regDialog.findViewById(R.id.nameField);
					EditText ip = (EditText) regDialog.findViewById(R.id.ipField);
					EditText port = (EditText) regDialog.findViewById(R.id.portField);
					EditText pwd = (EditText) regDialog.findViewById(R.id.pwdField);	

					tmppwd=pwd.getText().toString();
					tmpip=ip.getText().toString();
					tmpport=Integer.parseInt(port.getText().toString());

					progressThread = new Thread(mTask, "ProgressThread");

					
					myProgressDialog=new ProgressDialog(MainActivity.this, ProgressDialog.THEME_TRADITIONAL);
					
					myProgressDialog.setTitle("Please wait...");
					myProgressDialog.setMessage("Contacting the Server...");
					myProgressDialog.show();					
					
					if(!tmppwd.isEmpty()) progressThread.start();
					else {sendError(ErrorCodes.EMPTY_PWD_MSG, ErrorCodes.EMPTY_PWD); myProgressDialog.dismiss();}

					ReceiveService.NAME=name.getText().toString();
					ReceiveService.IP_SERVER=ip.getText().toString();
					ReceiveService.PORT_SERVER=Integer.parseInt(port.getText().toString());
					ReceiveService.PASSWORD=pwd.getText().toString();


				}
			})
			.setNegativeButton(R.string.backButton, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
				}
			});
			regDialog = builder.create();


			regDialog.show();
			EditText name = (EditText) regDialog.findViewById(R.id.nameField);
			EditText ip = (EditText) regDialog.findViewById(R.id.ipField);
			EditText port = (EditText) regDialog.findViewById(R.id.portField);
			name.setText(ReceiveService.NAME);
			ip.setText(ReceiveService.IP_SERVER);
			port.setText(ReceiveService.PORT_SERVER+"");
		}
	}



	public void showButtonListener(View v){

		int ctrl=GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

		if(ctrl==ConnectionResult.SUCCESS){
			Intent intent = new Intent();
			intent.setClass(this, Map.class);
			startActivity(intent);
		}
		else{
			Intent intent = new Intent();
			intent.setClass(this, Map_v1.class);
			startActivity(intent);
		}


	}

	public void alertButtonListener(View v){

		AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
		LayoutInflater inflater = MainActivity.this.getLayoutInflater();		
		builder.setView(inflater.inflate(R.layout.dialog_sender, null));

		builder
		.setPositiveButton(R.string.sendButton, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {

				RadioGroup rbg=(RadioGroup) sendDialog.findViewById(R.id.radioGroupAlert);
				RadioButton rb=(RadioButton) sendDialog.findViewById(rbg.getCheckedRadioButtonId());

				Sender2 sender2=new Sender2();
				sender2.sendMessage(new CustomMessage(CustomMessage.MESSAGE_TYPE_ALERT, ReceiveService.NAME, "BROADCAST", rb.getText().toString()), true);

				Toast toast = Toast.makeText(MainActivity.this, rb.getText().toString(), Toast.LENGTH_LONG);
				toast.show();
				sender2.closeSender();
			}
		})
		.setNegativeButton(R.string.backButton, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {

			}
		});
		sendDialog = builder.create();
		sendDialog.show();

	}

	public void sendButtonListener(View v){

		Intent intent = new Intent();
		intent.setClass(this, ChatMain.class);
		startActivity(intent);


	}

	public void geoLocButtonListener(View v){

		boolean on = ((ToggleButton) v).isChecked();

		if (!on) {
			GeoInfoService.activateGeoLocation.sendEmptyMessage(0);
			GeoInfoService.active_geoloc=false;

		} else {
			GeoInfoService.active_geoloc=true;
			LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
			if(locationManager==null) return;
			if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){

				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				LayoutInflater inflater = MainActivity.this.getLayoutInflater();		
				builder.setView(inflater.inflate(R.layout.dialog_gen_layout, null));

				builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
						MainActivity.this.startActivity(settingsIntent);
						GeoInfoService.activateGeoLocation.sendEmptyMessage(0);
					}
				});
				builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						GeoInfoService.activateGeoLocation.sendEmptyMessage(0);
					}
				});
				AlertDialog dialog = builder.create();
				dialog.setTitle("Warning! GPS Disabled");
				dialog.setMessage("Do you want enable GPS now?");
				dialog.show();
			}
			else{
				GeoInfoService.activateGeoLocation.sendEmptyMessage(0);
			}	    	
		}

	}

	public void closeButtonListener(View v){		
		notifier.destroyMainNotify();
		geoserviceActive=false;
		stopService(new Intent(MainActivity.this, ReceiveService.class));
		stopService(new Intent(MainActivity.this, GeoInfoService.class));
		end=true;
		sysActive=false;
		EditText name = (EditText) findViewById(R.id.mainConsole);
		name.setText("");
		writeConvAndUpdate();
		
		finish();
	}
	
	/**Memorizza le conversazioni in file in memoria*/
	public void writeConvAndUpdate(){
		if(ReceiveService.convStore==null)return;
		for(String alias: ReceiveService.convStore.keySet()){
			IO.writeOnMemory(this, alias,  ReceiveService.convStore.get(alias).getBytes());
		}
	}

	@Override
	protected void onStop(){
		super.onStop();
		active=false;
		notifier.destroyMainNotify();
		if(!end)notifier.mainNotification();

	}


	@Override
	protected void onPause(){
		super.onPause();
		active=false;
		notifier.destroyMainNotify();
		if(!end)notifier.mainNotification();
	}

	@Override
	protected void onResume(){
		super.onResume();
		active=true;
		notifier.destroyMainNotify();
		notifier.mainNotificationNoIntent();
		if(geoserviceActive)GeoInfoService.activateGeoLocation.sendEmptyMessage(0);
	}

}
